#include "stdafx.h"

HRESULT ClearSurface(LPDIRECTDRAWSURFACE7 surf, WORD iColor)
{
	if (surf==0)
		return NULL;
	DDBLTFX bltfx;
	ZeroMemory(&bltfx,sizeof(bltfx));
	bltfx.dwSize = sizeof(bltfx);
	bltfx.dwFillColor = iColor;

	HRESULT hr;
	hr = surf->Blt(0,0,0,DDBLT_WAIT | DDBLT_COLORFILL,&bltfx);
	return hr;
}

HRESULT DXDDInit(IDirectDraw7 **ppiDD,
				LPDIRECTDRAWSURFACE7 *primsurf,
				LPDIRECTDRAWSURFACE7 *backsurf,
				HWND hWnd, DWORD iWidth, DWORD iHeight,
				WORD iColors, BOOL *bFullScreen)
{
	int iRes;
	HRESULT hr;
	iRes = MessageBox(hWnd,L"Do you want to use fullscreen?",
		L"Fullscreen",MB_YESNO | MB_ICONQUESTION);
	hr = DirectDrawCreateEx(NULL,(VOID**)ppiDD, IID_IDirectDraw7, NULL);
	if (FAILED(hr))
		return hr;
	if (iRes == IDYES)
	{
		// Fullscreen
		*bFullScreen = TRUE;
		SetWindowLong(hWnd,GWL_STYLE,WS_POPUP);
		(*ppiDD)->SetCooperativeLevel(hWnd,
			DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);
		(*ppiDD)->SetDisplayMode(iWidth, iHeight,iColors,NULL,NULL);
	}
	else
	{
		//Windowed
		*bFullScreen = FALSE;
		RECT RectWnd;
		RECT RectClient;
		GetWindowRect(hWnd,&RectWnd);
		GetClientRect(hWnd,&RectClient);
		int iWidthWnd = iWidth + (RectWnd.right-RectWnd.left)-
			(RectClient.right-RectWnd.left);
		int iHeightWnd = iHeight + (RectWnd.bottom-RectWnd.top)-
			(RectClient.bottom-RectWnd.top);
		MoveWindow(hWnd,RectWnd.left,RectWnd.top,
			iWidthWnd,iHeightWnd,TRUE);
		(*ppiDD)->SetCooperativeLevel(hWnd,DDSCL_NORMAL);
	}
	DDSURFACEDESC2 desc;
	ZeroMemory(&desc,sizeof(desc));
	desc.dwSize = sizeof(desc);
	if (iRes == IDYES)
	{
		desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		desc.ddsCaps.dwCaps = 
			DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | 
			DDSCAPS_COMPLEX;
		desc.dwBackBufferCount = 1;
	}
	else
	{
		desc.dwFlags = DDSD_CAPS;
		desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	}
	hr = (*ppiDD)->CreateSurface(&desc, primsurf, 0);
	if (hr !=DD_OK)
		return hr;
	if (iRes == IDYES)
	{
		DDSCAPS2 surfcaps;
		ZeroMemory(&surfcaps,sizeof(surfcaps));
		surfcaps.dwCaps = DDSCAPS_BACKBUFFER;
		hr = (*primsurf)->GetAttachedSurface(&surfcaps,backsurf);
		if (hr != DD_OK)
			return hr;
		ClearSurface(*primsurf,0);
		ClearSurface(*backsurf,0);
	}
	else
	{
		// Clipper
		
		LPDIRECTDRAWCLIPPER DDClip;
		(*ppiDD)->CreateClipper(0,&DDClip,0);
		DDClip->SetHWnd(0,hWnd);
		(*primsurf)->SetClipper(DDClip);

		ZeroMemory(&desc,sizeof(desc));
		desc.dwSize = sizeof(desc);
		desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
		desc.dwWidth = iWidth;
		desc.dwHeight = iHeight;
		desc.ddsCaps.dwCaps = 
			DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
		hr = (*ppiDD)->CreateSurface(&desc,backsurf,0);
		if (hr != DD_OK)
			return hr;
	}

	return DD_OK;

}

HRESULT CreateCircle (IDirectDraw7 *piDD, LPDIRECTDRAWSURFACE7 *surf, WORD iColor, int iRadius, WORD Flags)
{
	if (((*surf) == NULL) && ((Flags & CRCIR_COLORONLY) != NULL))
	{
		return E_FAIL;
	}
	else
	{
		if (((*surf) != NULL) && ((Flags & CRCIR_COLORONLY) == NULL))
			return E_FAIL;
	}
	DDSURFACEDESC2 desc;

	ZeroMemory(&desc,sizeof(desc));
	desc.dwSize=sizeof(desc);
	if ((Flags & CRCIR_COLORONLY) == 0)
	{
		desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH |DDSD_CAPS;
		desc.dwWidth = 2 * iRadius;
		desc.dwHeight = 2 * iRadius;
		desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
		HRESULT hr = piDD->CreateSurface(&desc, surf,0);
		if (hr != DD_OK)
			return hr;
		ClearSurface((*surf),0);
	}
	if ((Flags & CRCIR_COLORONLY) != 0)
	{
		(*surf)->GetSurfaceDesc(&desc);
		iRadius = desc.dwWidth / 2;
	}
	ZeroMemory(&desc,sizeof(desc));
	desc.dwSize=sizeof(desc);
	if ((*surf)->Lock(0,&desc,DDLOCK_WAIT,0) == DD_OK)
	{
		BYTE *dst = (BYTE *)desc.lpSurface;
		int d;
		int iTwoRadius = 2 * iRadius;
		for (int i = 1; i < iRadius + 1; i++)
		{
			d = 2 * 
				(int) sqrt(
				(float)(iRadius * iRadius - (iRadius - i) * (iRadius - i))
				);

			for (int j = iTwoRadius - d; j < iTwoRadius + d; j = j + 2)
			{
				* (WORD *) (dst + j) = iColor;
			}
			dst = dst + desc.lPitch;
		}
		for (int i = iRadius; i < iTwoRadius; i++)
		{
			d = 2 * 
				(int) sqrt(
				(float)(iRadius * iRadius - (i - iRadius) * (i-iRadius))
				);

			for (int j = iTwoRadius - d; j < iTwoRadius + d; j = j + 2)
			{
				* (WORD *) (dst + j) = iColor;
			}
			dst = dst + desc.lPitch;
		}
		(*surf)->Unlock(0);
	}
//	delete desc;
	DDCOLORKEY colkey;
	colkey.dwColorSpaceLowValue=0;
	colkey.dwColorSpaceHighValue=0;
	(*surf)->SetColorKey(DDCKEY_SRCBLT, &colkey);
	return DD_OK;
}